#include "roadsPage.h"
#include "roundaboutPages.h"
#include <QVBoxLayout>
#include <QGridLayout>
#include <QLabel>
#include <QSlider>
#include <QSpinBox>
#include <QTextCodec>
#include <QCheckBox>
#include <QComboBox>
#include <QDebug>
#include <QSettings>

//----------------------zakladka ULICE----------------------------------

/*!
  \brief jedyny konstruktor tworzący zakładkę ulic

W konstruktorze tworzone są dwa layouty (główny RoadsPage::_mainLayout oraz RoadsPage::_galezieLayout) i
etykiety będące nagłówkami kolumn do właściwości gałęzi (RoadsPage::_wjazdZjazdLabel, RoadsPage::_liczbaPasowLabel,
RoadsPage::_czyPasyLabel oraz RoadsPage::_zaleznoscLabel), które są dodawane do RoadsPage::_galezieLayout.
Następnie wywoływana jest funkcja createNumBranchesWidgets() zajmująca się widgetami dotyczącymi liczby
gałęzi (tworzony jest trzeci layout _liczbaGaleziLayout).
Na koniec do głównego layouty dodawane sa dwa pozostałe klasowe layouty.
 */
 RoadsPage::RoadsPage(QWidget *parent, int numLanesOnBranch)
     : QWidget(parent), _liczbaPasowRondo(numLanesOnBranch)
 {
     QTextCodec::setCodecForTr (QTextCodec::codecForName ("UTF-8"));

     _mainLayout = new QVBoxLayout;
     _galezieLayout = new QGridLayout();
     //tworze niezmienne widgety (nagkłówki)

     _wjazdZjazdLabel = new QLabel(tr("Wjazd/Zjazd"));
     _liczbaPasowLabel  = new QLabel(tr("Liczba pasów"));
     _czyPasyLabel  = new QLabel(tr("Zebra"));
     _zaleznoscLabel  = new QLabel(tr("Zależność"));

     _galezieLayout->addWidget(_wjazdZjazdLabel, 0, 1, Qt::AlignCenter);
     _galezieLayout->addWidget(_liczbaPasowLabel, 0, 2, Qt::AlignCenter);
     _galezieLayout->addWidget(_czyPasyLabel, 0, 3, Qt::AlignCenter);
     _galezieLayout->addWidget(_zaleznoscLabel, 0, 4, Qt::AlignCenter);

     createNumBranchesWidgets();

     _mainLayout->addLayout(_liczbaGaleziLayout);//layout z iloscia galezi
     _mainLayout->addSpacing(12);
     _mainLayout->addLayout(_galezieLayout);//layout z galeziami
     _mainLayout->addStretch(1);
     setLayout(_mainLayout);

 }


 /*!
    Tworzy layout i widgety dotyczące ustawień liczby gałęzi (_liczbaGaleziLayout, _liczbaGaleziLabel, _liczbaGaleziSpinBox,
    _liczbacGaleziSlider) oraz ustawia zakres _liczbaGaleziSpinBox i _liczbacGaleziSlider.
    Po odczytaniu liczby gałęzi z opcji (zobacz \link stronaZapisOpcji \endlink) ustawia ją w _liczbaGaleziSpinBox i w zmiennej
    _ileGaleziStworzonych. Następnie wywołuje funkcję createBranchProperties() podając jako argument przed chwilą ustawianą wartość
    liczby gałęzi. W dalszej kolejności łączony jest za pomocą connecta _liczbacGaleziSlider z _liczbaGaleziSpinBox (tak aby zmiana wartości
    w jednym widgecie powodowała zmianę w drugim i na odwrót). Ponadto _liczbaGaleziSpinBox jest łączony ze slotem RoadsPage::changeNumBranches().
    Stworzone widgety są dodawane do _liczbaGaleziLayout. Na koniec ustawiana jest wartość RoadsPage::_prevNumBranches oraz emitowany sygnał
    changeNumBranchesForTram() podając jako argument liczbe gałęzi.
   */
 void RoadsPage::createNumBranchesWidgets()
 {
     _liczbaGaleziLayout = new QHBoxLayout();
     _liczbaGaleziLabel = new QLabel(tr("Liczba gałęzi"));
     _liczbaGaleziSpinBox = new QSpinBox();
     _liczbacGaleziSlider = new QSlider(Qt::Horizontal); //To jest numBranches
     _liczbaGaleziSpinBox->setRange(2, MAX_ROADS);
     _liczbacGaleziSlider->setRange(2, MAX_ROADS);

//     QSettings o("TabMar", "RoundaboutSimulator");//odczytuje ile galezi w opcjach zapisanych
//     _liczbaGaleziSpinBox->setValue(o.value("numBranches", 2).toInt());
//     _ileGaleziStworzonych = _liczbaGaleziSpinBox->value();
//     createBranchProperties(_liczbaGaleziSpinBox->value());

     connect(_liczbacGaleziSlider, SIGNAL(valueChanged(int)), _liczbaGaleziSpinBox, SLOT(setValue(int)));
     connect(_liczbaGaleziSpinBox, SIGNAL(valueChanged(int)), _liczbacGaleziSlider, SLOT(setValue(int)));
     connect(_liczbaGaleziSpinBox, SIGNAL(valueChanged(int)), this, SLOT(changeNumBranches(int)));

     _liczbaGaleziLayout->addWidget(_liczbaGaleziLabel);
     _liczbaGaleziLayout->addWidget(_liczbaGaleziSpinBox);
     _liczbaGaleziLayout->addWidget(_liczbacGaleziSlider);

     _prevNumBranches = _liczbaGaleziSpinBox->value(); // role _prevNumBranches opisałem już gdzie indziej. Szukaj dalej.

     emit changeNumBranchesForTram(_liczbaGaleziSpinBox->value());
 }

 //tworze wlasciwosci Branches i przypinam je do ich layoutu
 /*!
   \param numBranches liczba gałęzi, dlaktórych mają zostać stworzone widgety właściwości

   Funkcja wywoływana wewnątrz RoadsPage::createNumBranchesWidgets() oraz Roadspage::changeNumBranches(),
   czyli przy inicjalizacji opcji oraz później przy edytowaniu liczby gałęzi.
   Tworzy widgety opisujące właściwości gałęzi. Liczba tych widgetów nie jest stała i zależy od podanego argumentu.
   Stworzone widgety są dodawane do _galezieLayout. Aktualizowana jest także wartość zmiennej _ileGaleziStworzonych.
   Na koniec wywoływana jest funkcja RoadsPage::configureRoadsPage().
   */
 void RoadsPage::createBranchProperties(int numBranches)
 {
//     qDebug() << "void RoadsPage::createBranchProperties(" <<  numBranches << ") START";
     for (int i = 0; i < numBranches; i++)
     {
         _galazLabel.append( new QLabel(tr("Gałąź ")+QString::number(double(i))) );
         _kierunekGaleziComboBox.append( new QComboBox() );
         _liczbaPasowSpinBox.append( new QSpinBox );
         _zaleznoscComboBox.append( new QComboBox );
         _czyPasyCheckBox.append( new QCheckBox() );
         if (i+1 >= numBranches)
             _galaz2Label.append( new QLabel(tr("z gałęzią ")+QString::number(double(0))) );
         else
             _galaz2Label.append( new QLabel(tr("z gałęzią ")+QString::number(double(i+1))) );

            _galezieLayout->addWidget(_galazLabel[i], i+3, 0, Qt::AlignCenter);
            _galezieLayout->addWidget(_kierunekGaleziComboBox[i], i+3, 1, Qt::AlignCenter);
            _galezieLayout->addWidget(_liczbaPasowSpinBox[i], i+3, 2, Qt::AlignCenter);
            _galezieLayout->addWidget(_czyPasyCheckBox[i], i+3, 3, Qt::AlignCenter);
            _galezieLayout->addWidget(_zaleznoscComboBox[i], i+3, 4, Qt::AlignCenter);
            _galezieLayout->addWidget(_galaz2Label[i], i+3, 5, Qt::AlignCenter);
     }
     _ileGaleziStworzonych = numBranches;
//     qDebug() << "void RoadsPage::createBranchProperties(" <<  numBranches << ") STOP";
     configureRoadsPage();
 }


 /*!
   Funkcja wywoływana wewnątrz RoadsPage::createBranchProperties.
   Wspomaga funkcję createBranchProperties() poprzez odpowiednią konfigurację stworzonych widgetów.
   Konfiguracja zawiera w sobie ustawienia zakresu QSpinBoxa, dodanie odpowiednich elementów w listach rozwijanych
   oraz ustawienie domyślne, aby co druga gałąź była zjazdem (naprzemiennie z wjazdem), która nie może być sklejona
   (zjazd nie może być sklejony z wjazdem w ruchu prawostronnym).
   Na koniec tworzone są także connecty do QComboBoxów.
   */
 void RoadsPage::configureRoadsPage()
 {
     for (int i = 0; i < _ileGaleziStworzonych; i++)
     {
        _kierunekGaleziComboBox[i]->addItem(tr("Wjazd"));
        _kierunekGaleziComboBox[i]->addItem(tr("Zjazd"));
        _liczbaPasowSpinBox[i]->setRange(1,_liczbaPasowRondo);
        _zaleznoscComboBox[i]->addItem(tr("Rozłączona"));

        //domyslne ustawienia: - co druga gałąź zjazdem, która nie moze byc sklejona
        if (i%2 == 1)
        {
            _kierunekGaleziComboBox[i]->setCurrentIndex(1);  // zjazd
            _zaleznoscComboBox[i]->addItem(tr("Ma skrót"));
        }
        else
        {
            _kierunekGaleziComboBox[i]->setCurrentIndex(0);  // wjazd
            _zaleznoscComboBox[i]->addItem(tr("Sklejona"));
        }       
     }

    changeDirection(0);  // argument niepotrzebny

     for (int i = 0; i < _ileGaleziStworzonych; i++)
     {
         connect(_zaleznoscComboBox[i], SIGNAL(currentIndexChanged(int)), this, SLOT(changeDependences(int)) );
         connect(_kierunekGaleziComboBox[i], SIGNAL(currentIndexChanged(int)), this, SLOT(changeDirection(int)) );
         connect(_kierunekGaleziComboBox[i], SIGNAL(currentIndexChanged(int)), this, SLOT(checkEntryOutlet()) ); //spr czy jest co najmniej 1 wjazd i zjazd
     }
 }

 /*!
   \param newNumBranches - nowa liczba gałęzi

   Slot łączony z sygnałem w funkcji RoadsPage::createNumBranchesWidgets(). Jest on połączony z sygnałem wysyłanym, gdy wartość
   RoadsPage::_liczbaGaleziSpinBox zostanie zmieniona.
   Kolejne kroki tego slotu sprowadzają się do wywoływania odpowiednich funkcji pomocniczych.
   <ul>
   <li> Zapisywane są tymczasowe wartości na dysk za pomocą QSettings - funkcja RoadsPage::saveTmpSettings().
   <li> Usuwane są widgety przedstawiające właściwości gałęzi - funkcja RoadsPage::deleteBranchProperties().
   <li> Ustawiana jest nowa liczba gałęzi.
   <li> Tworzone są widgety właściwości dla nowej liczby gałęzi - funkcja RoadsPage::createBranchProperties().
   <li> Odczytanie wartości z tymczasowo zapisanych opcji (zapisywanych w punkcie pierwszym), żeby ustawić domyślnie wartości na takie jakie były przed zmianą liczby gałęzi.
   <li> Emitowany jest sygnał RoadPages::changeNumBranchesForTram() informujący o zmianie liczby gałęzi.
   <li> Uaktualniamy wartość RoadsPage::_prevNumBranches.
   </ul>
   */
void RoadsPage::changeNumBranches(int newNumBranches)
{
    saveTmpSettings();
    deleteBranchProperties();
    _ileGaleziStworzonych = newNumBranches;
    createBranchProperties(newNumBranches); 
    readTmpSettings();
    emit changeNumBranchesForTram(newNumBranches);

    _prevNumBranches = newNumBranches;  // zapamiętujemy ile teraz jest gałęzi. Przyda się to, gdy uzytkownik zmieni wartość spinBoxa, a my będziemy chcieli zapisać dotychczasowe ustawienia
}


/*!
  Slot jest łączony z sygnałem currentIndexChanged dla każdej zmiennej RoadsPage::_zaleznoscComboBox
w funkcji RoadsPage::configureRoadsPage(). Wywoływany, gdy zmieni się wartość w liście QComboBoxa opisującego zależności gałęzi.
Funkcja usuwa możliwość wyboru "sklejona" w liście zależności _zaleznoscComboBox jeżeli:
<ul>
<li>poprzednia gałąź i bieżąca jest wjazdem
<li>poprzednia/następna gałąź jest sklejona
<li>bierząca gałąź jest zjazdem
</ul>
Funkcja dodaje możliwość wyboru "sklejona" w liście zależności _zaleznoscComboBox jeżeli:
<ul>
<li>poprzednia i następna gałąź nie jest sklejona oraz bieżąca gałąź jest wjazdem,
a liczba elementów w liście jest mniejsza od dwóch.
</ul>
  */
void RoadsPage::changeDependences(int)
{
    int nastepny, poprzedni; //nastepny = i+1, poprzedni i-1
    for (int i = 0; i < _ileGaleziStworzonych; i++)
    {
        nastepny = plusModulo(i, 1, _ileGaleziStworzonych);
        poprzedni = minusModulo(i, 1, _ileGaleziStworzonych);

        if ( (_zaleznoscComboBox[poprzedni]->currentText() == tr("Sklejona")) ||
             (_zaleznoscComboBox[nastepny]->currentText() == tr("Sklejona")) ||
             (_kierunekGaleziComboBox[i]->currentText() == tr("Zjazd")) )
            usunSklejona(i); //usuwam sklejoną jeżeli nie może być

        if ( (_kierunekGaleziComboBox[poprzedni]->currentText() == tr("Wjazd")) &&
             (_kierunekGaleziComboBox[i]->currentText() == tr("Wjazd")))
            usunSklejona(poprzedni);

        if ((_zaleznoscComboBox[poprzedni]->currentText() != tr("Sklejona")) &&
            (_zaleznoscComboBox[nastepny]->currentText() != tr("Sklejona")) &&
            (_zaleznoscComboBox[i]->count() < 2) && (_kierunekGaleziComboBox[i]->currentText() == tr("Wjazd") )  )
            dodajSklejona(i);
    }
}

/*!
  \param i numer QComboBoxa, z którego ma zostać usunięty element

  Funkcja pomocnicza wykorzystywana w Roadspage::changeDependences().
  Usuwa z i-tego RoadsPage::_zaleznoscComboBox element "Sklejona".
  */
void RoadsPage::usunSklejona(int i)
{
    int index = _zaleznoscComboBox[i]->findText(tr("Sklejona"));
    if (index != -1)
        _zaleznoscComboBox[i]->removeItem(index);
}

/*!
  \param i numer QComboBoxa, do którego ma zostać dodany element

  Funkcja pomocnicza wykorzystywana w Roadspage::changeDependences().
  Dodaje do i-tego RoadsPage::_zaleznoscComboBox element "Sklejona".
  */
void RoadsPage::dodajSklejona(int i)
{
    int index = _zaleznoscComboBox[i]->findText(tr("Sklejona"));
    if (index == -1)
        _zaleznoscComboBox[i]->insertItem(1, (QString)tr("Sklejona"));
}

/*!
  \param ind niewykorzystywany. Numer indeksu zmienionego w _kierunekGaleziComboBox.

  Funkcja usuwa z wszystkich _zaleznoscComboBox element "Ma skrót" jeżeli odpowiadający QComboBoxowi kierunek gałęzi jest wjazdem,
  lub dodaje do _zaleznoscComboBox element "Ma skrót" jeżeli odpowiadający QComboBoxowi kierunek gałęzi jest zjazdem i nie ma takiego elementu.
  Następnie wywołuje RoadsPage::changeDependences(), gdyż nowe kierunki mogły wpłynąć na zależności.
  Na koniec znajdowany jest numer gałęzi, dla której nastąpiła zmiana i ten numer jest podawany jako argument emitowanego sygnału directionChanged();
  */
void RoadsPage::changeDirection(int ind)//wjazd/zjazd
{
    for (int i = 0; i < _ileGaleziStworzonych; i++)
    {
        if (_kierunekGaleziComboBox[i]->currentText() == tr("Wjazd"))
        {
            //usuń połączoną jesli jest
            int index = _zaleznoscComboBox[i]->findText(tr("Ma skrót"));
            if (index != -1)
                _zaleznoscComboBox[i]->removeItem(index);

            // Dodaj sklejoną jesli jej nie masz
            index = _zaleznoscComboBox[i]->findText(tr("Sklejona"));
            if (index == -1)
                _zaleznoscComboBox[i]->insertItem(2, (QString)tr("Sklejona"));
        }
        else
        {
            // usuń sklejoną, jeśli ją masz
            int index = _zaleznoscComboBox[i]->findText(tr("Sklejona"));
            if (index != -1)
                _zaleznoscComboBox[i]->removeItem(index);

            //dodaj połączoną jesli nie ma
            index = _zaleznoscComboBox[i]->findText(tr("Ma skrót"));
            if (index == -1)
                _zaleznoscComboBox[i]->insertItem(1, (QString)tr("Ma skrót"));
        }
    }

    changeDependences(0);
    //znajduje numer gałęzi dla którego nastąpiła zmiana
    int i = 0;
    foreach(QComboBox *combo, _kierunekGaleziComboBox)
    {
        if ( combo == (QComboBox*)sender() )
            break;
        i++;
    }
    emit directionChanged(i); //emituje numer gałęzi, w której zaszła zmiana wjazd/zjazd
}

/*!
  Slot połączony z sygnałem RoundaboutPage::changeNumLane(int). Odbiera informację o zmianie liczby pasów na rondzie.
  Update'owana jest maksymalna wartość liczby pasów na gałęzi.
  */
void RoadsPage::changeNumLanesFromRoadPages(int num)
{
    //przyszła wartość num zmieniona w pasach
    _liczbaPasowRondo = num;
    foreach (QSpinBox* qsb, _liczbaPasowSpinBox)
        qsb->setRange(1, _liczbaPasowRondo);
}

/*!
Funkcja usuwa wszystkie stworzone widgety dotyczące właściwości gałęzi. Funkcja "odwrotna" do createNumBranchesWidgets.
Wykorzystywana w funkcji changeNumBranches().
  */
void RoadsPage::deleteBranchProperties()
{
    foreach (QLabel * q, _galazLabel)
        delete q;
    foreach (QComboBox * q, _kierunekGaleziComboBox)
        delete q;
    foreach (QSpinBox * q, _liczbaPasowSpinBox)
        delete q;
    foreach (QCheckBox * q, _czyPasyCheckBox)
        delete q;
    foreach (QComboBox * q, _zaleznoscComboBox)
        delete q;
    foreach (QLabel * q, _galaz2Label)
        delete q;

    _galazLabel.clear();
    _kierunekGaleziComboBox.clear();
    _liczbaPasowSpinBox.clear();
    _czyPasyCheckBox.clear();
    _zaleznoscComboBox.clear();
    _galaz2Label.clear();
}

/*!
Funkcja zapisuje opcje dotyczące zakładki "Ulice" za pomocą QSettings. Więcej informacji o zapisie
\link stronaZapisOpcji opcji \endlink. Zmienna dependences jest zapisywana w postaci enum, dlatego w funkcji dokonywana jest też
zamiana wybranego tekstu w _zaleznoscComboBox na odpowiedni indeks typu wyliczeniowego.
  */
void RoadsPage::saveRoadsSettings()
{
    QSettings o("TabMar", "RoundaboutSimulator");
    //gałąź
    removeGroupSettings("Branch");
    o.setValue("numBranches", _liczbaGaleziSpinBox->value());
    o.beginWriteArray("Branch");
    for (int i = 0; i < _liczbaGaleziSpinBox->value(); i++)
    {
        o.setArrayIndex(i);
        o.setValue("numLanes", _liczbaPasowSpinBox[i]->value() );
        o.setValue("direction", _kierunekGaleziComboBox[i]->currentIndex());
        int dep = 0;
        if (_zaleznoscComboBox[i]->currentText() == tr("Rozłączona"))
            dep = 0;
        if (_zaleznoscComboBox[i]->currentText() == tr("Ma skrót"))
            dep = 1;
        if (_zaleznoscComboBox[i]->currentText() == tr("Sklejona"))
            dep = 2;
        o.setValue("dependences", dep);
        o.setValue("zebra", _czyPasyCheckBox[i]->checkState()); //jeżeli 0 to jest Uncheck, jeśli 2 to zaznaczony
    }
    o.endArray();
}

/*!
Funkcja odczytuje opcje dotyczące zakładki "Ulice" za pomocą QSettings z dysku. Więcej informacji o odczycie
\link stronaZapisOpcji opcji \endlink.
Początkowo ustawiana jest wartość 2 gałęzi i dopiero potem odczytywane i przypisywane są wartości z QSettings.
Na czas odczytywania i przypisywania wartości z opcji disconnecty są rozłączane i łączone z powrotem na koniec funkcji.
Podobnie jak w przypadku funkcji saveRoadsSettings() dokonywana jest zamiana typu wyliczeniowego (w takiej postaci zostały zapisane dane na dysk)
na aktualnie wybrany numer indeksu w _zaleznoscComboBox.
Na koniec wywoływana jest funkcja checkEntryOutlet() i emitowany jest sygnał changeNumBranchesForTram().
  */
void RoadsPage::readRoadsSettings()
{
    debug("readRoadsSettings start ");

    QSettings o("TabMar", "RoundaboutSimulator");
     _liczbaGaleziSpinBox->setValue(20);  // to make sure that a changeValue signal is emitted
    _liczbaGaleziSpinBox->setValue(o.value("numBranches", 0).toInt());
    _ileGaleziStworzonych = _liczbaGaleziSpinBox->value();

    debug("readRoadsSettings **** TU wszystkie pozycje powinny byc juz prawidlowe :( " + _liczbaGaleziSpinBox->text());

    o.beginReadArray("Branch");
    for (int i = 0; i < _liczbaGaleziSpinBox->value(); i++)
    {
        disconnect(_zaleznoscComboBox[i], SIGNAL(currentIndexChanged(int)), this, SLOT(changeDependences(int)) );
        disconnect(_kierunekGaleziComboBox[i], SIGNAL(currentIndexChanged(int)), this, SLOT(changeDirection(int)) );
        disconnect(_kierunekGaleziComboBox[i], SIGNAL(currentIndexChanged(int)), this, SLOT(checkEntryOutlet()) );

        o.setArrayIndex(i);
        _liczbaPasowSpinBox[i]->setValue(o.value("numLanes", 3).toInt());
        _kierunekGaleziComboBox[i]->setCurrentIndex(o.value("direction").toInt());

        /* okej; W tym momencie mam świeżo stworzone "preferencje" gałęzi. Dla wjazdów są odpowiednie zależności
           i dla zjazdów też. Tylko że,
          */

        int x = o.value("dependences").toInt();

        if (o.value("dependences").toInt() == 2)
        {
            int index = _zaleznoscComboBox[i]->findText(tr("Sklejona"));
            if (index < 0)
            {
                _zaleznoscComboBox[i]->insertItem(2, tr("Sklejona"));
                index = _zaleznoscComboBox[i]->findText(tr("Sklejona"));
                _zaleznoscComboBox[i]->setCurrentIndex(index);
            }
            else
                _zaleznoscComboBox[i]->setCurrentIndex(index);
        }
        else if (o.value("dependences").toInt() == 1)
        {
             int index = _zaleznoscComboBox[i]->findText(tr("Ma skrót"));
             if (index < 0)
             {
                 index = _zaleznoscComboBox[i]->findText(tr("Ma skrót"));
                 _zaleznoscComboBox[i]->insertItem(1, tr("Ma skrót"));
                 _zaleznoscComboBox[i]->setCurrentIndex(index);
             }
             else
                _zaleznoscComboBox[i]->setCurrentIndex(index);
        }
        else
            _zaleznoscComboBox[i]->setCurrentIndex(_zaleznoscComboBox[i]->findText(tr("Rozłączona")));

        if (_zaleznoscComboBox[i]->currentIndex() < 0)
            qDebug() << "---- chcialem, a nie moglem; x =" << x << endl <<
                        _zaleznoscComboBox[i]->itemText(0) << " " << _zaleznoscComboBox[i]->itemText(1) << _zaleznoscComboBox[i]->itemText(2);

        _czyPasyCheckBox[i]->setChecked(o.value("zebra", 0).toBool());

        connect(_zaleznoscComboBox[i], SIGNAL(currentIndexChanged(int)), this, SLOT(changeDependences(int)) );
        connect(_kierunekGaleziComboBox[i], SIGNAL(currentIndexChanged(int)), this, SLOT(changeDirection(int)) );
        connect(_kierunekGaleziComboBox[i], SIGNAL(currentIndexChanged(int)), this, SLOT(checkEntryOutlet()) );
    }
    o.endArray();

    checkEntryOutlet();
    changeDirection(0);


    emit changeNumBranchesForTram(_liczbaGaleziSpinBox->value());
}

/*!
  Zwraca liczbę gałęzi - wartość aktualnie ustawioną w _liczbaGaleziSpinBox.
  */
int RoadsPage::getNumBranches()
{
    return _liczbaGaleziSpinBox->value();
}

/*!
  Funkcja wywoływana w changeNumBranches().
Zapisuje na dysk tymczasowe opcje potrzebne podczas aktualizacji liczby dynamicznych widgetów.
Więcej na temat zapisu \link stronaZapisOpcji opcji \endlink
  */
void RoadsPage::saveTmpSettings()
{
    if ((_liczbaPasowSpinBox.size() > 0) && (_kierunekGaleziComboBox.size() > 0) &&
        (_zaleznoscComboBox.size() > 0) && (_czyPasyCheckBox.size() > 0) )
    {
        QSettings tmp("TabMar", "RoundaboutSimulatorTmp");
        //gałąź
        tmp.beginWriteArray("Branch");

        for (int i = 0; i < _prevNumBranches; i++)  // używam _prevNumBranches a nie aktualna wartość spinBoxa numBranches, bo chcę zapisać to co było
        {
            tmp.setArrayIndex(i);
            tmp.setValue("numLanes", _liczbaPasowSpinBox.at(i)->value() );
            tmp.setValue("direction", _kierunekGaleziComboBox.at(i)->currentIndex());
            tmp.setValue("dependences", _zaleznoscComboBox.at(i)->currentIndex());
            tmp.setValue("zebra", _czyPasyCheckBox.at(i)->checkState()); //jeżeli 0 to jest Uncheck, jeśli 2 to zaznaczony
        }
        tmp.endArray();
    }
}

/*!
  Odczytuje dane zapisane na dysku przez funkcję saveTmpSettings().
  Wywoływana wewnątrz funkcji changeNumBranches().
  Więcej informacji na temat zapisu/odczytu na dysk przy użyciu QSettings: \link stronaZapisOpcji Opcje \endlink.
  */
void RoadsPage::readTmpSettings()
{
    if ((_liczbaPasowSpinBox.size() > 0) && (_kierunekGaleziComboBox.size() > 0) &&
        (_zaleznoscComboBox.size() > 0) && (_czyPasyCheckBox.size() > 0) )
    {
        int number = 0;
        if (_prevNumBranches > _liczbaGaleziSpinBox->value())
            number = _liczbaGaleziSpinBox->value();
        else
            number = _prevNumBranches;
        QSettings tmp("TabMar", "RoundaboutSimulatorTmp");
        //gałąź
        tmp.beginReadArray("Branch");
        for (int i = 0; i < number; i++)
        {
            tmp.setArrayIndex(i);
            _liczbaPasowSpinBox[i]->setValue(tmp.value("numLanes", 3).toInt());
            _kierunekGaleziComboBox[i]->setCurrentIndex(tmp.value("direction").toInt());
            _zaleznoscComboBox[i]->setCurrentIndex(tmp.value("dependences").toInt());
            _czyPasyCheckBox[i]->setCheckState(Qt::CheckState(tmp.value("zebra", 3).toInt()));
        }
        tmp.endArray();
    }
}

/*!
Funkcja zlicza liczbę wjazdów i zjazdów ustawionych w opcjach.
Jeżeli jest 0 wjazdów to ostatni combobox ustawiam na wjazd. Natomiast jeżeli
jest 0 zjazdów to ostatni ComboBox ustawiam na zjazd.
Jest to slot połączony ze zmianą indeksu _kierunekGaleziComboBox. Ponadto wywoływany jest także w funkcji readRoadsSettings().
 */
void RoadsPage::checkEntryOutlet()
{
    int ileWjazdow = 0;
    int ileZjazdow = 0;
    for (int i = 0; i < _liczbaGaleziSpinBox->value(); i++)
    {
        if ( _kierunekGaleziComboBox[i]->currentText() == tr("Wjazd") )
            ileWjazdow++;
        else if( _kierunekGaleziComboBox[i]->currentText() == tr("Zjazd") )
            ileZjazdow++;
    }

    if (ileWjazdow == 0)
        _kierunekGaleziComboBox[_liczbaGaleziSpinBox->value()-1]->setCurrentIndex(0);
    else if (ileZjazdow == 0)
        _kierunekGaleziComboBox[_liczbaGaleziSpinBox->value()-1]->setCurrentIndex(1);
}


/*!
  \param i - indeks gałęzi, dla której ma być zwrócony kierunek
  \return Zwraca w postaci wyliczeniowej Direction kierunek i-tej gałęzi (wjazd/zjazd)
  */
Direction RoadsPage::getBranchDirection(int i)
{
    return Direction(_kierunekGaleziComboBox[i]->currentIndex());
}

/*!
\param i - indeks gałęzi, dla której ma być zwrócony rodzaj zależności
\return Zwraca w postaci wyliczeniowej Dependence rodzaj zależności i-tej gałęzi (Sklejona/Rozłączona/Ma skrót)
*/
Dependence RoadsPage::getBranchDependence(int i)
{
    if (_zaleznoscComboBox[i]->currentText() == QObject::tr("Sklejona"))
        return glued;
    if (_zaleznoscComboBox[i]->currentText() == QObject::tr("Rozłączona"))
        return none;
    if (_zaleznoscComboBox[i]->currentText() == QObject::tr("Ma skrót"))
        return connected;
    return none;
}
